﻿using NLog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using WorkManagerSystem.DataContent;
using WorkManagerSystem.DataContent.DataModels;
using WorkManagerSystem.Models;
using WorkManagerSystem.Tools;

namespace WorkManagerSystem.Controllers
{
    public class HomeController : Controller
    {
        private readonly WorkManagerContext workManagerContext = null;
        private static Logger logger = LogManager.GetCurrentClassLogger();
        public HomeController()
        {
            workManagerContext = new WorkManagerContext();
        }

        public ActionResult Index()
        {
            ViewBag.student = BuildStudentList(null);
            ViewBag.grade = BuildGradeList();
            ViewBag.book = BuildBookList();
            return View();
        }

        [HttpPost]
        public async Task<ActionResult> Index(SubjectPostModel subjectPostModel)
        {

            await Task.Run(() =>
            {
                Subject subject = new Subject();
                int stuId = int.Parse(subjectPostModel.StudentId);
                int graId = int.Parse(subjectPostModel.GradeId);
                int bookId = int.Parse(subjectPostModel.Book);

                ViewBag.student = BuildStudentList(graId);
                ViewBag.grade = BuildGradeList();
                ViewBag.book = BuildBookList();

                Students s = workManagerContext.Students.First(stu => stu.Id == stuId);
                Grades g = workManagerContext.Grades.First(gra => gra.Id == graId);
                Book book = workManagerContext.Books.First(bb => bb.Id == bookId);

                subject.Students = s;
                subject.Name = subjectPostModel.Chapter;
                subject.Book = book;
                try
                {
                    if (!string.IsNullOrEmpty(subjectPostModel.SoundCodePath))
                    {
                        if (System.IO.File.Exists(subjectPostModel.SoundCodePath))
                        {
                            //string rootUploadDir = Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString()) + "//upload";
                            string rootUploadDir = Server.MapPath("~//upload");
                            string fileExtension = Path.GetExtension(subjectPostModel.SoundCodePath);
                            string bookPath = rootUploadDir + $"//{subjectPostModel.Book}";
                            string gradePath = rootUploadDir + $"//{subjectPostModel.Book}//{g.Name}";
                            string chapterPath = rootUploadDir + $"//{subjectPostModel.Book}//{g.Name}" + $"//{subjectPostModel.Chapter}";
                            if (!Directory.Exists(bookPath))
                            {
                                Directory.CreateDirectory(bookPath);
                            }
                            if (!Directory.Exists(gradePath))
                            {
                                Directory.CreateDirectory(gradePath);
                            }
                            if (!Directory.Exists(chapterPath))
                            {
                                Directory.CreateDirectory(chapterPath);
                            }
                            string newFilePath = Path.Combine(rootUploadDir + $"//{subjectPostModel.Book}//{g.Name}//{subjectPostModel.Chapter}", $"{s.Code}_{s.Name}{fileExtension}");
                            if (System.IO.File.Exists(newFilePath))
                            {
                                System.IO.File.Delete(newFilePath);
                            }
                            System.IO.File.Move(subjectPostModel.SoundCodePath, newFilePath);

                            //获取程序根目录
                            //string tmpRootDir = Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString());
                            string tmpRootDir = Server.MapPath("~//upload");
                            //转换成URL相对路径
                            string tmpNewFilePath = newFilePath.Replace(tmpRootDir, "");
                            tmpNewFilePath = tmpNewFilePath.Replace(@"/", @"/");
                            subject.SoundCodePath = tmpNewFilePath;
                        }
                    }
                    else
                    {
                        subject.Remark = subjectPostModel.Reason;
                    }
                }
                catch (Exception ex)
                {
                    logger.Debug("@@@作业表单提交时异常@@@" + ex.Message.ToString() + "@@@" + ex.StackTrace);
                    JsHelper.AlertAndRedirect("提交失败", "/home/index");
                }
                workManagerContext.Subject.Add(subject);
                workManagerContext.SaveChangesAsync();
                //ViewBag.msg = "提交成功！";
            });

            ModelState.Clear(); //清空表单数据
            JsHelper.AlertAndRedirect("提交成功", "/home/index");
            return View();

        }

        public ActionResult OverView()
        {
            ViewBag.student = BuildStudentList(null);
            ViewBag.grade = BuildGradeList();
            ViewBag.book = BuildBookList();

            var list = workManagerContext.Subject.Where(s => s.DelFlag == false)
                .Select(ss => new SubjectViewModel
                {
                    Name = ss.Name,
                    SoundCodePath = ss.SoundCodePath,
                    Grade = ss.Grade,
                    Remark = ss.Remark,
                    StudentName = ss.Students.Name,
                    GradeName = ss.Students.Grades.Name,
                    BookName = ss.Book.Name
                }).ToList();

            ViewBag.sum = list.Count;
            ViewBag.finishCount = list.Count(a => a.SoundCodePath != null);
            ViewBag.unFinishCount = list.Count(a => a.SoundCodePath == null);
            return View(list);
        }

        [HttpPost]
        public ActionResult OverView(int bookId, int gradeId, int studentId, string charpt)
        {
            ViewBag.student = BuildStudentList(gradeId);
            ViewBag.grade = BuildGradeList();
            ViewBag.book = BuildBookList();

            var list = workManagerContext.Subject.Where(s => s.DelFlag == false);
            //var list=workManagerContext.Database.SqlQuery<Subject>("").AsQueryable();

            var msg = "请选择：";
            if (bookId == 0)
            {
                msg += " 课本";
            }
            if (gradeId == 0)
            {
                msg += " 班级";
            }
            if (bookId > 0)
            {
                list = list.Where(s => s.Book.Id == bookId);
            }
            if (gradeId > 0)
            {
                list = list.Where(s => s.Students.Grades.Id == gradeId);
            }
            if (!string.IsNullOrEmpty(charpt))
            {
                list = list.Where(s => s.Name == charpt);
            }
            var temp = list.Select(ss => new SubjectViewModel
            {
                Name = ss.Name,
                SoundCodePath = ss.SoundCodePath,
                Grade = ss.Grade,
                Remark = ss.Remark,
                StudentName = ss.Students.Name,
                GradeName = ss.Students.Grades.Name,
                BookName = ss.Book.Name
            }).ToList();

            if (msg != "请选择：")
            {
                ViewBag.msg = msg;
            }
            ViewBag.sum = temp.Count();
            ViewBag.finishCount = temp.Count(a => a.SoundCodePath != null);
            ViewBag.unFinishCount = temp.Count(a => a.SoundCodePath == null);
            return View(temp);
        }

        /// <summary>
        /// 供前端页面调用上传文件，将大型文件打包成块存储
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Upload()
        {
            string fileName = Request["name"];
            string fileRelName = fileName.Substring(0, fileName.LastIndexOf('.'));//设置临时存放文件夹名称
            int index = Convert.ToInt32(Request["chunk"]);//当前分块序号
            var guid = Request["guid"];//前端传来的GUID号
            var dir = Server.MapPath("~/Upload");//文件上传目录
            dir = Path.Combine(dir, fileRelName);//临时保存分块的目录
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);
            string filePath = Path.Combine(dir, index.ToString());//分块文件名为索引名，更严谨一些可以加上是否存在的判断，防止多线程时并发冲突
            var data = Request.Files["file"];//表单中取得分块文件
            //if (data != null)//为null可能是暂停的那一瞬间
            //{
            data.SaveAs(filePath);//报错
            //}

            return Json(new { code = 200, desc = "接收完毕" });
        }

        public ActionResult AllManage()
        {
            ViewBag.student = BuildStudentList(null);
            ViewBag.grade = BuildGradeList();
            ViewBag.book = BuildBookList();

            var list = workManagerContext.Subject.Where(s => s.DelFlag == false)
                .Select(ss => new SubjectViewModel
                {
                    Id = ss.Id,
                    Name = ss.Name,
                    SoundCodePath = ss.SoundCodePath,
                    Grade = ss.Grade,
                    Remark = ss.Remark,
                    StudentName = ss.Students.Name,
                    GradeName = ss.Students.Grades.Name,
                    BookName = ss.Book.Name
                }).ToList();

            ViewBag.sum = list.Count;
            ViewBag.finishCount = list.Count(a => a.SoundCodePath != null);
            ViewBag.unFinishCount = list.Count(a => a.SoundCodePath == null);
            return View(list);
        }

        [HttpPost]
        public ActionResult AllManage(int bookId, int gradeId, int studentId, string charpt)
        {
            ViewBag.student = BuildStudentList(gradeId);
            ViewBag.grade = BuildGradeList();
            ViewBag.book = BuildBookList();

            var list = workManagerContext.Subject.Where(s => s.DelFlag == false);
            //var list=workManagerContext.Database.SqlQuery<Subject>("").AsQueryable();

            var msg = "请选择：";
            if (bookId == 0)
            {
                msg += " 课本";
            }
            if (gradeId == 0)
            {
                msg += " 班级";
            }
            if (bookId > 0)
            {
                list = list.Where(s => s.Book.Id == bookId);
            }
            if (gradeId > 0)
            {
                list = list.Where(s => s.Students.Grades.Id == gradeId);
            }
            if (!string.IsNullOrEmpty(charpt))
            {
                list = list.Where(s => s.Name == charpt);
            }
            var temp = list.Select(ss => new SubjectViewModel
            {
                Id = ss.Id,
                Name = ss.Name,
                SoundCodePath = ss.SoundCodePath,
                Grade = ss.Grade,
                Remark = ss.Remark,
                StudentName = ss.Students.Name,
                GradeName = ss.Students.Grades.Name,
                BookName = ss.Book.Name
            }).ToList();

            if (msg != "请选择：")
            {
                ViewBag.msg = msg;
            }
            ViewBag.sum = temp.Count();
            ViewBag.finishCount = temp.Count(a => a.SoundCodePath != null);
            ViewBag.unFinishCount = temp.Count(a => a.SoundCodePath == null);
            return View(temp);
        }

        public ActionResult Del(int id)
        {
            try
            {
                var obj = workManagerContext.Subject.Find(id);
                if (obj != null)
                {
                    workManagerContext.Subject.Remove(obj);
                    workManagerContext.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                logger.Debug("@@@作业删除操作异常@@@" + ex.Message.ToString() + "@@@" + ex.StackTrace);
            }
            return Redirect("/home/AllManage");
        }

        /// <summary>
        /// 将上传到服务器的分块文件进行从新编译生成指定文件
        /// </summary>
        /// <returns></returns>
        public async Task<ActionResult> Merge()
        {
            return await Task.Run(() =>
            {
                string finalPath = "";
                try
                {
                    var guid = Request["guid"];//GUID
                    var uploadDir = Server.MapPath("~/Upload");//服务器的Upload 文件夹 物理地址
                    var fileName = Request["fileName"];//文件全名（包括扩展名）
                    string fileRelName = fileName.Substring(0, fileName.LastIndexOf('.'));//获取文件名
                    var dir = Path.Combine(uploadDir, fileRelName);//临时文件夹          
                    var files = Directory.GetFiles(dir);//获得下面的所有文件
                    finalPath = Path.Combine(uploadDir, fileName);//最终的文件名（demo中保存的是它上传时候的文件名，实际操作肯定不能这样）
                    FileStream fs;
                    using (fs = new FileStream(finalPath, FileMode.Create))
                    {
                        foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))//排一下序，保证从0-N Write
                        {
                            var bytes = System.IO.File.ReadAllBytes(part);
                            fs.Write(bytes, 0, bytes.Length);
                            bytes = null;
                            System.IO.File.Delete(part);//删除分块
                        }
                        fs.Flush();
                    }
                    Directory.Delete(dir);//删除文件夹
                }
                catch (Exception ex)
                {
                    logger.Debug("@@@文件切片合并操作异常@@@" + ex.Message.ToString() + "@@@" + ex.StackTrace);
                }
                return Json(new { finalPath = finalPath });//随便返回个值，实际中根据需要返回
            });
        }

        public ActionResult GetStudent(int gradId)
        {
            return Json(BuildStudentList(gradId), JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 构建学生信息下拉框数据
        /// </summary>
        /// <returns></returns>
        private List<SelectListItem> BuildStudentList(int? gradeId)
        {
            //从数据库中学生读取
            var studentList = workManagerContext.Students.Where(s => s.DelFlag == false);
            if (gradeId.HasValue)
            {
                studentList = studentList.Where(s => s.Grades.Id == gradeId);
            }
            var list = studentList.Select(c => new { Id = c.Id, Name = c.Name }).ToList();
            var selectStudentItemList = new List<SelectListItem>() {
                new SelectListItem(){Value="0",Text="请选择学生",Selected=true}
            };
            var selectStudentList = new SelectList(list, "Id", "Name");
            selectStudentItemList.AddRange(selectStudentList);
            return selectStudentItemList;
        }

        /// <summary>
        /// 构建班级信息下拉框数据
        /// </summary>
        /// <returns></returns>
        private List<SelectListItem> BuildGradeList()
        {
            //从数据库中班级读取
            var gradeList = workManagerContext.Grades.Where(s => s.DelFlag == false).Select(c => new { Id = c.Id, Name = c.Name }).ToList(); ;
            var selectGradeItemList = new List<SelectListItem>() {
                new SelectListItem(){Value="0",Text="请选择班级",Selected=true}
            };
            var selectGradeList = new SelectList(gradeList, "Id", "Name");
            selectGradeItemList.AddRange(selectGradeList);
            return selectGradeItemList;
        }

        /// <summary>
        /// 构建课本信息下拉框数据
        /// </summary>
        /// <returns></returns>
        private List<SelectListItem> BuildBookList()
        {
            //从数据库中 课本读取
            var bookList = workManagerContext.Books.Where(s => s.DelFlag == false).Select(c => new { Id = c.Id, Name = c.Name }).ToList(); ;
            var selectBookItemList = new List<SelectListItem>() {
                new SelectListItem(){Value="0",Text="请选择课本",Selected=true}
            };
            var selectBookList = new SelectList(bookList, "Id", "Name");
            selectBookItemList.AddRange(selectBookList);
            return selectBookItemList;
        }
    }
}